/***************************************************************
 *
 * Filename：Serve.cpp
 * Abstract：the design of TCP and UDP 
 * version ：1.0
 * 
 * Copyright (c) 2011 SCUT DT&P FY&XC
 * 
***************************************************************/
#include <QtNetwork>
#include "Serve.h"

Serve::Serve()
{
	msgmng = new MessagePRO;
        gbk = QTextCodec::codecForName("gb18030");
        utg8 = QTextCodec::codecForName("utf-8");
	udpSocket = new QUdpSocket(this);
        udpSocket->bind(IPMSG_DEFAULT_PORT,QUdpSocket::ShareAddress);
	qDebug()<<"Port:"<<IPMSG_DEFAULT_PORT;
        //监听UDP数据包，如果有数据包抵达调用receiveessag槽进行处理
	connect(udpSocket, SIGNAL(readyRead()), this, SLOT(receiveUdp())); 

	broadcast(6291457, NULL);
}

//广播函数
void Serve::broadcast(unsigned long command, QString extend)
{
	MessagePRO *msg = new MessagePRO;
	msg->command = command;
        qDebug()<<"Username:"<<msg->username;
        qDebug()<<"extend:"<<msg->extend;
	QByteArray datagram;
        datagram.append(QString("%1:%2:")
			.arg(msg->version)
                        .arg(msg->packetno));
        QByteArray data2 = gbk->fromUnicode(msg->username);
        QByteArray data = ":";
        QByteArray data3 = gbk->fromUnicode(msg->hostname);
        QByteArray data4;
        data4.append(QString(":%1:")
                     .arg(msg->command));
        QByteArray data5;
        if(extend == NULL) {
            data5="";
        }
        else {
            data5 = gbk->fromUnicode(extend);
        }
        datagram += data2;
        datagram += data;
        datagram += data3;
        datagram += data4;
        datagram += data5;

        qDebug()<<"Broadcast:"<<datagram<<"hahahahahahaahaah";
        udpSocket->writeDatagram(datagram, qint64(datagram.size()),
			QHostAddress::Broadcast, IPMSG_DEFAULT_PORT);
        qDebug()<<QHostAddress::Broadcast<<"in Serve::broadcast";

}

//发送数据函数
void Serve::sendUdp(MessagePRO *msg,bool flag)
{
	qDebug() << "---sendUdp---";
	qDebug() << "Username:"		<<msg->username;
	qDebug() << "Hostname:" 	<<msg->hostname;
	qDebug() << "HostAddress:" 	<<msg->address;
	qDebug() << "Version:" 		<<msg->version;
	qDebug() << "Packetno:"		<<msg->packetno;
	qDebug() << "Command:" 		<<msg->command;
	qDebug() << "Extend:" 		<<msg->extend;
	QHostInfo info=QHostInfo::fromName("localhost");
	foreach(QHostAddress addr, info.addresses())
        {
		qDebug()<<"Localhost-Address:"<<addr;
	}
        /*
        if (!info.addresses().isEmpty()) {
		qDebug()<<"info.addresses().indexOf(msg->address)= "<< info.addresses().indexOf(msg->address) ;
		qDebug()<<"msg->address:"<<msg->address;
		qDebug()<<"msgmng->address:"<<msgmng->address;

                if(( msg->address==msgmng->address) && (msg->command != 96) && (msg->command != 99) ) {
			//emit addUser(msg);
			emit msgSendMsg(msg);
			qDebug()<<"sendUdp---to localhost";
			return;
                }
        }*/

        QByteArray datagram;
        datagram.append(QString("%1:%2:")
                        .arg(msg->version)
                        .arg(msg->packetno));
        QByteArray data2;
        QByteArray data=":";
        QByteArray data3;
        QByteArray data4;
        QByteArray data5;
        //扩展用
        if (flag == true) {
            qDebug()<<"ipmsg in flag true";
            data2 = msg->username.toLocal8Bit();
            data3 = msg->hostname.toLocal8Bit();
            data4.append(QString(":%1:")
                            .arg(msg->command));
                    if(msg->extend == NULL) {
                        data5="";
                    }
                    else {
                        data5 = gbk->fromUnicode(msg->extend);
                    }

        }
        else {
        qDebug()<<"QLan in flag false";
        data2.append(QString("%1").arg(msg->username));
        data3.append(QString("%1").arg(msg->hostname));
	data4.append(QString(":%1:")
			.arg(msg->command));

        if(msg->extend == NULL) {
            data5="";
        }
        else {
            data5 = gbk->fromUnicode(msg->extend);
        }
                }

	datagram += data2;
        datagram += data;
	datagram += data3;
	datagram += data4;
	datagram += data5;

	qDebug()<<"SendUdp:"<<datagram;
	udpSocket->writeDatagram(datagram.data(), (qint64)datagram.size(),
	              msg->address, IPMSG_DEFAULT_PORT);
}

//对接收UDP的数据处理的函数
void Serve::receiveUdp()
{
        qDebug()<<"Begin ReceiveUdp"<<"in Serve::receiveUdp";
	while (udpSocket->hasPendingDatagrams())
	{
		QByteArray datagram;
		QHostAddress addr;
		quint16 port;
		qDebug()<<"|=------------------------------------------------------------------------=|";
		datagram.resize(udpSocket->pendingDatagramSize());
		udpSocket->readDatagram(datagram.data(), datagram.size(), &addr, &port);
		qDebug()<<"Ip:Port "<<addr<<":"<<port;

		//开始解码
                int receiveVersion = 1;                         //保存解码数据包版本
                unsigned long receivePacketno = 0;              //保存数据包的编号
                QString receiveUsername = NULL;                 //保存解码后的数据包的用户昵称
                QString receiveHostname = NULL;                 //保存解码数据包后的主机名
                unsigned long receiveCommand = 0;               //保存命令字
                QString receiveExtend = NULL;                   //保存附加信息
		if(!datagram.isEmpty())
		{
			QList<QByteArray> list=datagram.split (':');
			QListIterator<QByteArray> i(list);
			for( int j = 0 ; i.hasNext() ; j++ )
				switch(j)
				{
					case 0:
						receiveVersion = atoi(i.next());
						break;
					case 1:
                                                receivePacketno = atoi(i.next());
                                                break;
					case 2:
                                                receiveUsername = gbk->toUnicode(i.next());
						break;
					case 3:
                                                receiveHostname = gbk->toUnicode(i.next());
						break;
					case 4:
                                                receiveCommand = atol(i.next());
						break;
					case 5:
                                                receiveExtend = gbk->toUnicode(i.next());
						break;
					default:
                                                receiveExtend = receiveExtend+ ":" + gbk->toUnicode(i.next());
						break;
				}	
		}
               // if (flag == true) {
                    //qDebug()<<"gbk_code in Serve::sendUdp";
                    //receiveUsername = receiveUsername;
                    qDebug()<<"uf_code in Serve::sendUdp";
                    //qDebug()<<msg->username;

                    //receiveHostname = UtoG(receiveHostname);
                    //receiveExtend = UtoG(receiveExtend);
                    //receiveExtend = receiveExtend;

              // }*/
		qDebug()<<"ReciveUdp:"<<datagram;
                qDebug()<<"Username:"<<receiveUsername<<"aaaaa";
                qDebug()<<"Command:"<<receiveCommand;
                qDebug()<<"Hostname:"<<GtoU(receiveHostname);
		qDebug()<<"Version:"<<receiveVersion;
		qDebug()<<"Packetno:"<<receivePacketno;
		qDebug()<<"Extend:"<<receiveExtend;
		if(receiveUsername == QHostInfo::localHostName())
		{
			msgmng->address = addr;
		}
		unsigned long recvCmd;
		unsigned long recvOpt;
		recvCmd = GET_MODE(receiveCommand);
		qDebug()<<"recvCmd:"<<recvCmd;
		recvOpt = GET_OPT(receiveCommand);
		qDebug()<<"recvOpt:"<<recvOpt;

		MessagePRO *msg;
		msg = msgmng->makeMng(receiveUsername, receiveHostname, receiveCommand, receiveExtend, addr);

		QByteArray datagramm;
		MessagePRO *m;
		m = msgmng->makeMng(receiveUsername, receiveHostname, receiveCommand, receiveExtend, addr);
                //如果对方要求发收到信息确认，这发送信息确认，这个是聊天信息等相关
		if(recvCmd == IPMSG_SENDMSG || receiveCommand == 2097440 || recvCmd == 0)
		{
			m->username = QHostInfo::localHostName();
			m->hostname = QHostInfo::localHostName()+"*";
			m->address = addr;
			m->command = 33;
			//m->command=IPMSG_ANSENTRY;
			datagramm.append(QString("%1:%2:%3:%4:%5:%6")
				.arg(m->version)
				.arg(receivePacketno)
				.arg(m->username)
				.arg(m->hostname)
				.arg(m->command)
				.arg(receivePacketno));
			qDebug()<<"SSSSendUdp:"<<datagramm;
			udpSocket->writeDatagram(datagramm.data(), (qint64)datagramm.size(),msg->address, IPMSG_DEFAULT_PORT);
		}


		switch (recvCmd)
		{
			case IPMSG_BR_ENTRY:
				msgBrEntry(msg);
				break;

			case IPMSG_BR_EXIT:
				emit msgBrExit(msg);
				break;

			case IPMSG_ANSENTRY:
				msgAnsEntry(msg);
				break;

			case IPMSG_BR_ABSENCE:
				msgBrAbsence(msg);
				break;

			case IPMSG_SENDMSG:
				emit addUser(msg);
                                emit msgSendMsg(msg);
                                QSound::play("./sounds/msg.wav");
				break;

			case IPMSG_RECVMSG:
				msgRecvMsg(msg);
				break;

			case IPMSG_READMSG:
			case IPMSG_ANSREADMSG:
				msgReadMsg(msg);
				break;

			case IPMSG_BR_ISGETLIST2:
				msgBrIsGetList(msg);
				break;

			case IPMSG_OKGETLIST:
				msgOkGetList(msg);
				break;

			case IPMSG_GETLIST:
				msgGetList(msg);
				break;

			case IPMSG_ANSLIST:
				msgAnsList(msg);
				break;

			case IPMSG_GETINFO:
				msgGetInfo(msg);
				break;

			case IPMSG_SENDINFO:
				msgSendInfo(msg);
				break;

			case IPMSG_GETPUBKEY:
				msgGetPubKey(msg);
				break;

			case IPMSG_ANSPUBKEY:
				msgAnsPubKey(msg);
				break;

			case IPMSG_GETABSENCEINFO:
				msgGetAbsenceInfo(msg);
				break;

			case IPMSG_SENDABSENCEINFO:
				msgSendAbsenceInfo(msg);
				break;

			case IPMSG_RELEASEFILES:
				msgReleaseFiles(msg);
				break;
                        case IPMSG_GETFILEDATA:
                                msgRevcFile(msg);
                                QSound::play("./sounds/info.wav");
                                break;
                        case IPMSG_REFUSEDATA:
                                msgRefuseSFile(msg);
                                QSound::play("./sounds/info.wav");
                                break;
                        case IPMSG_USERCHGPHOTO:
                                emit chgphoto(msg);
                                break;
                            }
	}	
}

// 在线信息处理
void Serve::msgBrEntry(MessagePRO *msg)
{
        QSound::play("./sounds/Global.wav");
        qDebug()<<"msgBrEntry address:"<<msg->address;
	qDebug()<<"["<<QDateTime::currentDateTime().toString(tr("yyyy-MM-dd  hh:mm:ss"))<<"]  "<<msg->username<<"is online."; 
	msg->command=IPMSG_ANSENTRY;
	msg->extend="";
        MessagePRO *sendmsg = new MessagePRO;
        sendmsg->address = msg->address;
        sendmsg->command = msg->command;
        sendmsg->extend =  msg->extend;
        emit addUser(msg);
        sendUdp(sendmsg);

        //显示新用户登录事件
        //SubWindow::recordTextEdit->append( "\n[ " + QDateTime::currentDateTime().toString(tr("yyyy-MM-dd  hh:mm:ss"))
        //				+ tr(" ]  System information \n\t") + msg->hostSub.userName);
			
}

//接收回应消息处理
void Serve::msgAnsEntry(MessagePRO *msg)
{
	emit addUser(msg);
	qDebug()<<"["<<QDateTime::currentDateTime().toString(tr("yyyy-MM-dd  hh:mm:ss"))<<"]  "<<msg->username<<"Reply to broadcast  "<<msg->extend; 

}

void Serve::msgBrAbsence(MessagePRO *msg){(void)(msg);}

void Serve::msgRevcFile(MessagePRO *msg)
{
    qDebug()<<"----msgRevcFile----";
    qDebug()<<"UserAddress:"<<msg->address;
    qDebug()<<"theFileName:"<<msg->extend;
    emit addUser(msg);
    emit msgRevcFileName(msg);
}
void Serve::msgRefuseSFile(MessagePRO *msg)
{
    qDebug()<<"----msgRevcFile----";
    qDebug()<<"UserAddress:"<<msg->address;
    emit msgRefuseFile(msg);
}

void Serve::msgRecvMsg(MessagePRO *msg){(void)(msg);}
void Serve::msgReadMsg(MessagePRO *msg){(void)(msg);}
void Serve::msgBrIsGetList(MessagePRO *msg){(void)(msg);}
void Serve::msgOkGetList(MessagePRO *msg){(void)(msg);}
void Serve::msgGetList(MessagePRO *msg){(void)(msg);}
void Serve::msgAnsList(MessagePRO *msg){(void)(msg);}
void Serve::msgGetInfo(MessagePRO *msg){(void)(msg);}
void Serve::msgSendInfo(MessagePRO *msg){(void)(msg);}
void Serve::msgGetPubKey(MessagePRO *msg){(void)(msg);}
void Serve::msgAnsPubKey(MessagePRO *msg){(void)(msg);}
void Serve::msgGetAbsenceInfo(MessagePRO *msg){(void)(msg);}
void Serve::msgSendAbsenceInfo(MessagePRO *msg){(void)(msg);}
void Serve::msgReleaseFiles(MessagePRO *msg){(void)(msg);}
void Serve::msgInfoSub(MessagePRO *msg){(void)(msg);}
